#include "stm32f10x.h"
#include "GPIO.h"
#include "delay.h"
#include "IIC.h"

//------------------------------------
void IIC_Start(void);                   //起始信号
void IIC_Stop(void);                    //停止信号
void IIC_SendAck(u8 ack);          			//应答ACK
u8  IIC_WaitAck(void);                  //读ack
void IIC_SendByte(u8 dat);         			//IIC单个字节写
u8 IIC_ReceiveByte(void);              	//IIC单个字节读

uint16_t SDA_GPIO_Pin;
uint16_t SCL_GPIO_Pin;
GPIO_TypeDef *IIC_GPIOx;

void IIC_Init(GPIO_TypeDef *GPIOx, uint16_t SCL_GPIO_Pin_n, uint16_t SDA_GPIO_Pin_n)
{
	

	SDA_GPIO_Pin = SDA_GPIO_Pin_n;
	SCL_GPIO_Pin = SCL_GPIO_Pin_n;
	IIC_GPIOx = GPIOx;	  

	GPIOx_Output(GPIOx, SCL_GPIO_Pin_n | SDA_GPIO_Pin_n, GPIO_Speed_50MHz, GPIO_Mode_Out_PP);

}

//SDA 输出
void SDA_Out()
{
// 	GPIO_InitTypeDef  GPIO_InitStructure;
//   GPIO_InitStructure.GPIO_Pin = SDA_GPIO_Pin;
//   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
//   GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);
	GPIOx_Output(IIC_GPIOx, SCL_GPIO_Pin | SDA_GPIO_Pin, GPIO_Speed_50MHz, GPIO_Mode_Out_PP);
}

//SDA 输入
void SDA_In()
{
// 	GPIO_InitTypeDef  GPIO_InitStructure;
//   GPIO_InitStructure.GPIO_Pin = SDA_GPIO_Pin;
//   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
//   GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);
	
	GPIOx_Input(IIC_GPIOx, SDA_GPIO_Pin, GPIO_Mode_IPU);
}


/**************************************
起始信号
**************************************/
void IIC_Start(void)
{
	SDA_Out();
	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1);      //拉高数据线
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线
	Delay_Nus(5);                                    //延时
	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0);      //数据线产生下降沿
	Delay_Nus(5);    
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线
}

/**************************************
结束信号
**************************************/
void IIC_Stop(void)
{
	SDA_Out();
	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0);      //拉低数据线
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线
	Delay_Nus(5);
	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1);      //数据线产生上升沿
	Delay_Nus(5);
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void IIC_SendAck(u8 ack)
{	
	SDA_Out();
	
	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, ack);    //ack
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线
	Delay_Nus(5);
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线
	Delay_Nus(5);	

}

u8 IIC_WaitAck(void) 	 //返回值=1表示有ACK; //返回值=0表示无ACK.                       
{
	u8 mcy;
	SDA_In();
	
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线
	Delay_Nus(5);
	mcy = GPIOx_getValue(IIC_GPIOx, SDA_GPIO_Pin);
	GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线
	Delay_Nus(5);
	SDA_Out();
	return mcy;

}

void IIC_SendByte(u8 SendByte) //数据从高位MSB到低位LSB发送
{
	u8 i=8;
	SDA_Out();
	while(i--)
	{
		//GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线, SCL为低电平SDA才可以变动
	 // Delay_Nus(1);
		if(SendByte&0x80)
		{
			GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1);    //SDA数据
		}
		else 
		{
			GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 0);    //SDA数据
		}
		SendByte<<=1;
		GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线,
		Delay_Nus(5);
		GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线
		Delay_Nus(5);
	}
	IIC_WaitAck();
}

u8 IIC_ReceiveByte(void)  //数据从高位到低位
{ 
	u8 i=8;
	u8 ReceiveByte=0;
	SDA_In();

	GPIOx_setValue(IIC_GPIOx, SDA_GPIO_Pin, 1);    //SDA上拉，准备接受数据;				
	while(i--)
	{
		ReceiveByte<<=1;      
		GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 1);      //拉高时钟线,
		Delay_Nus(5);	
		if(GPIOx_getValue(IIC_GPIOx, SDA_GPIO_Pin))
		{
			ReceiveByte|=0x01;
		}
		GPIOx_setValue(IIC_GPIOx, SCL_GPIO_Pin, 0);      //拉低时钟线
		Delay_Nus(5);	
	}
	
	SDA_Out();
	return ReceiveByte;	
	
}
